package net.jgrm.redisadvanced.service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Redis List类型操作服务接口
 */
public interface RedisListService {

    /**
     * 将元素添加到列表的头部
     *
     * @param key    键
     * @param values 值
     * @return 列表的长度
     */
    Long leftPush(String key, Object... values);

    /**
     * 将元素添加到列表的尾部
     *
     * @param key    键
     * @param values 值
     * @return 列表的长度
     */
    Long rightPush(String key, Object... values);

    /**
     * 从列表头部弹出一个元素
     *
     * @param key   键
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 弹出的元素
     */
    <T> T leftPop(String key, Class<T> clazz);

    /**
     * 从列表尾部弹出一个元素
     *
     * @param key   键
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 弹出的元素
     */
    <T> T rightPop(String key, Class<T> clazz);

    /**
     * 阻塞式从列表头部弹出元素
     *
     * @param key      键
     * @param timeout  超时时间
     * @param timeUnit 时间单位
     * @param clazz    返回值类型
     * @param <T>      返回值泛型
     * @return 弹出的元素
     */
    <T> T leftPop(String key, long timeout, TimeUnit timeUnit, Class<T> clazz);

    /**
     * 阻塞式从列表尾部弹出元素
     *
     * @param key      键
     * @param timeout  超时时间
     * @param timeUnit 时间单位
     * @param clazz    返回值类型
     * @param <T>      返回值泛型
     * @return 弹出的元素
     */
    <T> T rightPop(String key, long timeout, TimeUnit timeUnit, Class<T> clazz);

    /**
     * 获取列表的长度
     *
     * @param key 键
     * @return 列表的长度
     */
    Long size(String key);

    /**
     * 获取列表指定范围的元素
     *
     * @param key   键
     * @param start 开始索引
     * @param end   结束索引
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 元素列表
     */
    <T> List<T> range(String key, long start, long end, Class<T> clazz);

    /**
     * 根据索引获取列表中的元素
     *
     * @param key   键
     * @param index 索引
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 元素
     */
    <T> T index(String key, long index, Class<T> clazz);

    /**
     * 设置列表中指定索引位置的元素值
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     */
    void set(String key, long index, Object value);

    /**
     * 移除列表中指定的元素
     *
     * @param key   键
     * @param count 移除的数量，正数从左向右，负数从右向左，0表示移除所有
     * @param value 值
     * @return 移除的元素数量
     */
    Long remove(String key, long count, Object value);

    /**
     * 裁剪列表，保留指定范围的元素
     *
     * @param key   键
     * @param start 开始索引
     * @param end   结束索引
     */
    void trim(String key, long start, long end);

    /**
     * 从一个列表的尾部弹出元素并添加到另一个列表的头部
     *
     * @param sourceKey      源列表键
     * @param destinationKey 目标列表键
     * @param clazz          返回值类型
     * @param <T>            返回值泛型
     * @return 移动的元素
     */
    <T> T rightPopAndLeftPush(String sourceKey, String destinationKey, Class<T> clazz);

    /**
     * 阻塞式从一个列表的尾部弹出元素并添加到另一个列表的头部
     *
     * @param sourceKey      源列表键
     * @param destinationKey 目标列表键
     * @param timeout        超时时间
     * @param timeUnit       时间单位
     * @param clazz          返回值类型
     * @param <T>            返回值泛型
     * @return 移动的元素
     */
    <T> T rightPopAndLeftPush(String sourceKey, String destinationKey, long timeout, TimeUnit timeUnit, Class<T> clazz);
}